gusucode.com > 现代通信系统——使用MATLAB(+全部程序) > 现代通信系统——使用MATLAB(+全部程序)/现代通信系统——使用MATLAB(+全部程序)/Matlab 程序/Chapter10/programs/prgs/depfun/eyesampl.m
function [sys, x0, str, ts] = eyesampl(t,x,u,flag,... timeRange, boundary, storeLength, eyeLine, scatterLine, sampleTime) % EYESAMPL Simulink eye diagram and scatter plot --- sampled time version. % [SYS, X0, STR, TS] = EYESAMPL(T,X,U,FLAG,TIMERANGE,BOUNDARY,STORELENGTH,EYELINE,SCATTERLINE,SAMPLETIME) % % This M-file is designed to be used in a Simulink S-function block. % It plots eyediagram against time and the scatter plot. % The parameter for the block of this figure are: % % timeRange Time range = [Digit Sample Time, Plot offset, Decision offset] % boundary Lower and upper boundary of the Y axis. % storeLength Keep number of traces in storage for print purpose. % eyeLine Line type for eye-pattern diagram (0 for no such plot) % scatterLine Symbol type for scatter plot (0 for no such plot) % sampleTime [Update sample time, update offset] % % This file takes scalar input or 2 dimensional vector input % % Set this M-file up in an S-function block. % Set the function parameter up as a four element vector % which defines the axis of the graph. The line type must be in % quotes. % % See also PLOT, SFUNYST, SFUNXY, EYEDIASI % Copyright 1996-2001 The MathWorks, Inc. % $Revision: 1.27 $ $Date: 2001/04/05 04:38:01 $ switch flag, %%%%%%%%%%%%%%%%%% % Initialization % %%%%%%%%%%%%%%%%%% case 0, [sys,x0,ts] = mdlInitializeSizes(... timeRange, boundary, storeLength, eyeLine, scatterLine, sampleTime); SetBlockCallbacks(gcbh); %%%%%%%%%% % Update % %%%%%%%%%% case 2, sys = mdlUpdate(t,x,u,... timeRange, boundary, storeLength, eyeLine, scatterLine, sampleTime); %%%%%%%%%%%%%%%%%%% % Next Sample Hit % %%%%%%%%%%%%%%%%%%% case 4, sys = mdlGetTimeOfNextVarHit(t, x, u); %%%%%%%%%%%%%%%%%%% % Unhandled flags % %%%%%%%%%%%%%%%%%%% case {1, 3, 9 } sys=[]; %%%%%%%%% % Start % %%%%%%%%% case 'Start' LocalBlockStartFcn %%%%%%%% % Stop % %%%%%%%% case 'Stop' LocalBlockStopFcn %%%%%%%%%%%%%% % NameChange % %%%%%%%%%%%%%% case 'NameChange' LocalBlockNameChangeFcn %%%%%%%%%%%%% % Load,Copy % %%%%%%%%%%%%% case { 'LoadBlock', 'CopyBlock' } LocalBlockLoadCopyFcn %%%%%%%%%%%%%%% % DeleteBlock % %%%%%%%%%%%%%%% case 'DeleteBlock' LocalBlockDeleteFcn %%%%%%%%%%%%%%%% % DeleteFigure % %%%%%%%%%%%%%%%% case 'DeleteFigure' LocalFigureDeleteFcn %%%%%%%%%%%%%%%%%%%% % Unexpected flags % %%%%%%%%%%%%%%%%%%%% otherwise if ischar(flag), errmsg=sprintf('Unhandled flag: '' %s''', flag); else errmsg=sprintf('Unhandled flag: %d', flag); end error(errmsg); end % end eyesampl % %============================================================================= % mdlInitializeSizes % Return the sizes, initial conditions, and sample times for the S-function. %============================================================================= % function [sys,x0,ts] = mdlInitializeSizes(... timeRange, boundary, storeLength, eyeLine, scatterLine, sampleTime); % % call simsizes for a sizes structure, fill it in and convert it to a sizes array. % sizes = simsizes; sizes.NumContStates = 0; sizes.NumDiscStates = 3; % 3 discrete states sizes.NumOutputs = 0; sizes.NumInputs = -1; % dynamically sized input vector sizes.DirFeedthrough = 0; % the meter does not have direct feedthrough sizes.NumSampleTimes = 1; sys = simsizes(sizes); % % initialize the initial condition % x0 = [0, 0, 0]; % figure handle, u[last] input, last_mod_time % x(1), the figure handle. if isempty(sampleTime) sampleTime = [-1 0]; end; if length(sampleTime) < 2 sampleTime(2) = 0; end ts = [sampleTime(1), sampleTime(2)]; % % str is always an empty matrix % str = []; % end mdlInitializeSizes % %============================================================================ % mdlGetTimeOfNextVarHit % Return the time of the next hit for this block. Note that the result % is absolute time. %============================================================================ % function sys = mdlGetTimeOfNextVarHit(t, x, u); if sampleTime(1) > 0 sys = t + sampleTime(1); else sys = []; end; % end mdlGetTimeOfNextVarHit % %============================================================================= % mdlUpdate % Handle discrete state updates, sample time hits, and major time step % requirements. %============================================================================= % function sys = mdlUpdate(t,x,u,... timeRange, boundary, storeLength, eyeLine, scatterLine, sampleTime); % % Locate the figure window associated with this block. If it's not a valid % handle (it may have been closed by the user), then return. % figureHandle = GetEyesamplFigure(gcbh); if ~ishandle(figureHandle) return; end; threshold = .2; eye_plot = ~((eyeLine(1)==0) + (eyeLine(1)=='0')); scatter_plot = ~((scatterLine(1)==0) + (scatterLine(1) == '0')); len_u = length(u); if scatter_plot & (len_u > 2) sl_name = get_param(0,'CurrentSystem'); block = get_param(sl_name ,'CurrentBlock'); error(['Please set scatter plot line type to be zero in block ', sl_name, '/', block]); if len_u > 2 error('The input signal length should be no larger than two.') end; end; plot_type = eye_plot + scatter_plot; % in case of no plot if plot_type <= 0 return; end; if length(timeRange) < 2 timeRange(2) = 0; else timeRange(2) = rem(rem(timeRange(2), timeRange(1)) + timeRange(1), timeRange(1)); end; if length(timeRange) < 3 timeRange(3) = timeRange(1)/2 + timeRange(2); end; % initialize the figure if x(1) == 0 h_fig = x(1); % Initialize graph sl_name = gcs; block = get_param(sl_name,'CurrentBlock'); sl_name_gcs = sl_name; if ~isempty(find(sl_name=='/')) sl_name = sl_name(find(sl_name=='/')+1 : length(sl_name)); end; [n_b, m_b]= size(block); if n_b < 1 error('Cannot delete block while simulating'); elseif n_b > 1 error('Something wrong in get_param, You don''t have the current Simulink') end; % if new_figure | old_figure % generate a new figure here. x(1) = figureHandle; if plot_type == 1 %open a single window figure delete(allchild(x(1))); figurePosition = get(x(1),'Position'); figurePosition(3) = 360; set(x(1), ... 'Visible','on',... 'Position', figurePosition ); plt(1) = axes('Unit','norm',... 'Pos',[.08, .08 .87,.87],... 'Clipping', 'on',... 'Parent', x(1),... 'NextPlot','Add' ,... 'HandleVisibility', 'off'); elseif plot_type == 2 % open a double window figure delete(allchild(x(1))); figurePosition = get(x(1),'Position'); figurePosition(3) = 660; set(x(1), ... 'Visible','on',... 'Position', figurePosition ); plt(1) = axes('Unit','norm',... 'Pos',[.08, .08 .8/2,.87],... 'Clipping', 'on',... 'Parent', x(1),... 'NextPlot','Add',... 'HandleVisibility', 'Off'); plt(2) = axes('Unit','norm',... 'Pos',[.08+.5, .08 .8/2,.87],... 'Parent', x(1),... 'NextPlot','Add',... 'HandleVisibility', 'Off'); end; i = 1; if eye_plot eye_plot = plt(i); i = i+1; set(x(1),'CurrentAxes',eye_plot); ax = []; lines = eyeLine; for j = 1:len_u+1; [col, lines] = strtok(lines, '/'); if length(col) <= 1 col = 'k-'; end; if lower(col(1)) == 'n' ax(j) = 0 else [linest, markst] = LineTypeSeparation(col(2:length(col))); ax(j) = plot(0,0,col,... 'Erasemode','none',... 'Color',col(1),... 'LineStyle',linest,... 'Marker', markst,... 'Parent', eye_plot); set(ax(j), 'XData', [], 'YData', []); end; end; set(eye_plot,... 'Xlim',[rem(timeRange(2)/timeRange(1),1)... *timeRange(1), timeRange(1)+timeRange(2)], ... 'Ylim',[boundary(1), boundary(2)], 'Clipping', 'on'); set(eye_plot,'UserData',[ax, 0 ]); % | | |==>space for time points % | |==> number of NaN added % |===> have size of length(u) end; if (scatter_plot) scatter_plot = plt(i); i = i + 1; set(x(1),'CurrentAxes',scatter_plot); ax = []; lines = scatterLine; for j = 1:len_u [col, lines] = strtok(lines, '/'); if length(col) <= 1 col = 'k-'; end; if ((len_u == 2) & (j == 2)) ax(j) = 0; else if lower(col(1)) == 'n' ax(j) = 0 else [linest, markst] = LineTypeSeparation(col(2:length(col))); ax(j) = plot(0,0,col,... 'Erasemode','none',... 'Color',col(1),... 'LineStyle',linest,... 'Marker', markst,... 'Parent', scatter_plot); if col(2) == '.' set(ax(j), 'MarkerSize', 10); end; set(ax(j), 'XData', [], 'YData', []); end; end; end; if len_u == 2 set(scatter_plot,... 'Xlim',[boundary(1), boundary(2)], ... 'Ylim',[boundary(1), boundary(2)]); else set(scatter_plot,... 'Xlim',[-1, 1],... 'Ylim',[boundary(1), boundary(2)]); end; set(scatter_plot,'UserData',[ax, abs(scatterLine)]); end; set(x(1),'UserData',[eye_plot, scatter_plot, timeRange, boundary, abs(eyeLine)]); % 1 2 3 6 8 set_param(sl_name_gcs, 'userdata', x(1)); % end; elseif x(1) < 0 % figure has been closed. return; end; plot_flag_test = allchild(0); if isempty(plot_flag_test) return; elseif isempty(find(plot_flag_test == x(1))) x(1) = -1; return; end; handles = get(x(1), 'UserData'); len_u = length(u); changed_boundary = 0; if max(boundary ~= handles(6:7)) > 0 changed_boundary = 1; end; mod_time = rem((t - timeRange(2))/timeRange(1), 1) * timeRange(1) + timeRange(2); triggered = 0; if (mod_time >= timeRange(3)) & (x(2) < timeRange(3)) triggered = 1; end; x(2) = mod_time; if handles(1) & eye_plot %eye_pattern plot sub_han = get(handles(1),'UserData'); changed_timeRange = 0; if max(timeRange ~= handles(3:5)) > 0 changed_timeRange = 1; end; if changed_boundary set(handles(1), 'Ylim', boundary); end; if changed_timeRange %this is a complicated process. Deal it later. end; len_h_userdata = length(handles); changed_line_type = 0; if (length(eyeLine) ~= len_h_userdata-7) changed_line_type = 1; elseif max(abs(eyeLine) ~= handles(8:len_h_userdata)) changed_line_type = 1; else changed_line_type = 0; end; if changed_line_type lines = eyeLine; for i = 1 : len_u+1 [col, lines] = strtok(lines, '/'); if length(col) <= 1 col = 'k-'; end; if sub_han(i) [linest, markst] = LineTypeSeparation(col(2:length(col))); set(sub_han(i), ... 'Color',col(1),... 'LineStyle',linest,... 'Marker', markst); end; end; set(x(1),'UserData',[handles(1:7), abs(eyeLine)]); end; mod_time = rem((t - timeRange(2))/timeRange(1), 1)... * timeRange(1) + timeRange(2); last_time = x(3); x(3) = mod_time; if (mod_time < last_time) if storeLength <= 0 storeLength = 1; end %hit the boundary of switching point. pre_point = mod_time + timeRange(1); aft_point = mod_time; ind = []; if sub_han(len_u+2) >= storeLength ind = find( isnan( sub_han( len_u + 3:length(sub_han) ) ) ); sub_han(len_u+3:ind(max(1, length(ind)-storeLength))) = []; sub_han(len_u+2) = sum( isnan( sub_han( len_u + 3:length(sub_han) ) ) ); end; sub_han(len_u + 2) = sub_han(len_u + 2) + 1; sub_han = [sub_han t NaN t]; set(handles(1),'UserData',sub_han); for i = 1 : len_u if sub_han(i) tmp_x = get(sub_han(i), 'XData'); tmp_y = get(sub_han(i), 'YData'); if ~isempty(ind) tmp_x(1:ind(max(1, length(ind)-storeLength))-len_u-2) = []; tmp_y(1:ind(max(1, length(ind)-storeLength))-len_u-2) = []; end; set(sub_han(i), 'XData',[tmp_x, pre_point, NaN, aft_point],... 'YData',[tmp_y, u(i), NaN, u(i)]); end; end; else set(handles(1), 'UserData',[get(handles(1), 'UserData') t]) for i = 1 : len_u if sub_han(i) set(sub_han(i), 'XData', [get(sub_han(i), 'XData'), mod_time], ... 'YData', [get(sub_han(i), 'YData'), u(i)]); end; end; end; if triggered & sub_han(len_u) & (t > 0) if storeLength <= 0 storeLength = 1; end tmp_x = get(sub_han(len_u + 1), 'XData'); tmp_y = get(sub_han(len_u + 1), 'YData'); if length(tmp_x) > 3*storeLength tmp_x(1:3) = []; tmp_y(1:3) = []; end; tmp_x = [timeRange(3), timeRange(3)]; tmp_y = [get(handles(1), 'YLim')]; set(sub_han(len_u + 1), 'XData', tmp_x, 'YData', tmp_y); end; end; if handles(2) & triggered & (t>0) & scatter_plot if storeLength <= 0 storeLength = 1; end %scatter plot sub_han = get(handles(2), 'UserData'); if changed_boundary set(handles(2), 'Ylim', boundary); if len_u == 2 set(handles(2), 'Xlim', boundary); end; end; len_h_userdata = length(sub_han); changed_line_type = 0; if (length(scatterLine) ~= len_h_userdata - len_u) changed_line_type = 1; elseif max(abs(scatterLine) ~= sub_han(len_u+1:len_h_userdata)) changed_line_type = 1; end; if changed_line_type lines = scatterLine; for i = 1 : len_u [col, lines] = strtok(lines, '/'); if length(col) <= 1 col = 'k-'; end; if ~((i == 2) & (len_u == 2)) [linest, markst] = LineTypeSeparation(col(2:length(col))); set(sub_han(i), 'Color',col(1),... 'LineStyle',linest,... 'Marker', markst); if col(2) == '.' set(sub_han(i), 'MarkerSize', 10); else set(sub_han(i), 'MarkerSize', 6); end; end; end; set(handles(2), 'UserData',[sub_han(1:len_u), abs(scatterLine)]); end; if len_u == 2 tmp_x = get(sub_han(1), 'XData'); tmp_y = get(sub_han(1), 'YData'); if length(tmp_x) > 2*storeLength tmp_x(1:2) = []; tmp_y(1:2) = []; end; tmp_x = [tmp_x, u(1), NaN]; tmp_y = [tmp_y, u(2), NaN]; set(sub_han(1), 'XData', tmp_x, 'YData', tmp_y); else for i = 1 : len_u tmp_x = get(sub_han(i), 'XData'); tmp_y = get(sub_han(i), 'YData'); if length(tmp_x) > 2*storeLength tmp_x(1:2) = []; tmp_y(1:2) = []; end; tmp_x = [tmp_x, 0, NaN]; tmp_y = [tmp_y, u(i), NaN]; set(sub_han(i), 'XData', tmp_x, 'YData', tmp_y); end; end; end; sys = x; % end mdlUpdate % %============================================================================= % LocalFigureDeleteFcn % This is the Graph figure window's DeleteFcn. The figure window is % being deleted, update the Graph block's UserData to reflect the change. %============================================================================= % function LocalFigureDeleteFcn % % Get the block associated with this figure and set it's figure to -1 % SetEyesamplFigure(gcbh, get_param(gcbh,'userdata')); close(gcbf); % end LocalFigureDeleteFcn % %============================================================================= % LocalBlockStartFcn % Function that is called when the simulation starts. Initialize the % Graph scope figure. %============================================================================= % function LocalBlockStartFcn % % get the figure associated with this block, create a figure if it doesn't % exist % figureHandle = GetEyesamplFigure(gcbh); if ~ishandle(figureHandle), figureHandle = CreateEyesamplFigure; end ud = get(figureHandle,'UserData'); set(figureHandle,'UserData',ud); % end LocalBlockStartFcn % %============================================================================= % LocalBlockStopFcn % At the end of the simulation, set the line's X and Y data to contain % the complete set of points that were acquire during the simulation. % Recall that during the simulation, the lines are only small segments from % the last time step to the current one. %============================================================================= % function LocalBlockStopFcn % % Locate the figure window associated with this block. If it's not a valid % handle (it may have been closed by the user), then return. % figureHandle=GetEyesamplFigure(gcbh); if ishandle(figureHandle), % % Get UserData of the figure. % ud = get(figureHandle,'UserData'); % Currently do nothing in LocalBlockStopFcn end % end LocalBlockStopFcn % %============================================================================= % LocalBlockNameChangeFcn % Function that handles name changes on the Bit-Error Meter. %============================================================================= % function LocalBlockNameChangeFcn % % the figure handle is stored in the block's UserData % figureHandle = GetEyesamplFigure(gcbh); if ishandle(figureHandle), set(figureHandle,'Name',get_param(gcbh,'Name')); end % end LocalBlockNameChangeFcn % %============================================================================= % LocalBlockLoadCopyFcn % Function that initializes the Bit-Error Meter's UserData when it is % loaded from an mdl file and when it is copied. %============================================================================= % function LocalBlockLoadCopyFcn SetEyesamplFigure(gcbh,[]); % end LocalBlockLoadCopyFcn % %============================================================================= % LocalBlockDeleteFcn % Function that handles the Bit-Error Meter's deletion from a block % diagram. %============================================================================= % function LocalBlockDeleteFcn % % the figure handle is stored in the block's UserData % figureHandle = GetEyesamplFigure(gcbh); if ishandle(figureHandle), delete(figureHandle); SetEyesamplFigure(gcbh,[]); end % end LocalBlockDeleteFcn % %============================================================================= % GetEyesamplFigure % Retrieves the figure window associated with this S-function Bit-Error Meter % from the block's parent subsystem's UserData. %============================================================================= % function figureHandle=GetEyesamplFigure(block) if strcmp(get_param(block,'BlockType'),'S-Function'), block=get_param(block,'Parent'); end ud = get_param(block,'UserData'); if ishandle(ud) figureHandle = ud; else if isempty(ud) ud.figureHandle = []; set_param(block,'UserData', ud); end; figureHandle = ud.figureHandle; end; if isempty(figureHandle), figureHandle = -1; end % end GetEyesamplFigure % %============================================================================= % SetEyesamplFigure % Stores the figure window associated with this S-function Bit-Error Meter % in the block's parent subsystem's UserData. %============================================================================= % function SetEyesamplFigure(block,figureHandle) if strcmp(get_param(block,'BlockType'),'S-Function'), block=get_param(block,'Parent'); end ud = get_param(block,'UserData'); ud.figureHandle = figureHandle; set_param(block,'UserData',ud); % end SetEyesamplFigure % %============================================================================= % CreateEyesamplFigure % Creates the figure window associated with this S-function Bit-Error Meter. %============================================================================= % function figureHandle=CreateEyesamplFigure % % create the figure and the axes % a = allchild(0); b = findobj(a, 'Name', get_param(gcbh,'Name')); if isempty(b) figureHandle = figure(... 'Units', 'points',... 'Position', [10 10 360 350],... 'NumberTitle', 'off',... 'Name', get_param(gcbh,'Name'),... 'Visible', 'off', ... 'IntegerHandle','off',... 'DeleteFcn', 'eyesampl([],[],[],''DeleteFigure'')'... ); else figureHandle = b; end; set(0, 'CurrentFigure', figureHandle); % % store the block's handle in the figure's UserData % ud.Block = gcbh; %ud.figureHandle = figureHandle; % % squirrel the figure handle away in the current block, and put the % various handles into the figure's UserData % SetEyesamplFigure(gcbh,figureHandle); set(figureHandle,'HandleVisibility','callback','UserData',ud); % end CreateEyesamplFigure % %============================================================================= % SetBlockCallbacks % This sets the callbacks of the block if it is not a reference. %============================================================================= % function SetBlockCallbacks(block) % % the actual source of the block is the parent subsystem % block=get_param(block,'Parent'); % % if the block isn't linked, issue a warning, and then set the callbacks % for the block so that it has the proper operation % if strcmp(get_param(block,'LinkStatus'),'none'), % warnmsg=sprintf(['The Eye-Pattern diagram block ''%s'' should be replaced with a ' ... % 'new version from the com_sour block library'],... % block); % warning(warnmsg); callbacks={ 'CopyFcn', 'eyesampl([],[],[],''CopyBlock'')' ; 'DeleteFcn', 'eyesampl([],[],[],''DeleteBlock'')' ; 'LoadFcn', 'eyesampl([],[],[],''LoadBlock'')' ; 'StartFcn', 'eyesampl([],[],[],''Start'')' ; 'StopFcn' 'eyesampl([],[],[],''Stop'')' ; 'NameChangeFcn', 'eyesampl([],[],[],''NameChange'')' ; }; for i=1:length(callbacks) if ~strcmp(get_param(block,callbacks{i,1}),callbacks{i,2}) set_param(block,callbacks{i,1},callbacks{i,2}); end end end % end SetBlockCallbacks % %=============================================================== % Local Function % This is used to separate the line type and mark type. %=============================================================== % function [linest, markst] = LineTypeSeparation(linetype) % take out the marks linest = linetype; linidx = [findstr(linetype, '.'), ... findstr(linetype, 'o'), ... findstr(linetype, 'x'), ... findstr(linetype, '+'), ... findstr(linetype, '*'), ... findstr(linetype, 's'), ... findstr(linetype, 'd'), ... findstr(linetype, 'v'), ... findstr(linetype, '^'), ... findstr(linetype, '<'), ... findstr(linetype, '>'), ... findstr(linetype, 'p'), ... findstr(linetype, 'h')]; markst = 'none'; if ~isempty(linidx) markst = linetype(linidx); linest(linidx) = []; end; if isempty(linest) linest = 'none'; end; %%%%%%%%%%%%%%%%%%%%%%%% % End of EYESAMPL.M % %%%%%%%%%%%%%%%%%%%%%%%%